//
//  BLWebViewController.m
//  GuChat
//
//  Created by iBenz on 15-3-26.
//  Copyright (c) 2015年 Guzhi Tech. All rights reserved.
//

#import "BLWebViewController.h"
#import "UIWebView+TS_JavaScriptContext.h"
#import <JavaScriptCore/JavaScriptCore.h>
#import "JSExcuteObject.h"
#import <WebKit/WebKit.h>
#import "WKWebView+Category.h"

static NSString *const WebToViewUserInfo   = @"gzinfo.html";

@interface UIView (Snapshot)
@end

@implementation UIView (Snapshot)

- (UIImage *)snapshot {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);
    [self.layer renderInContext:UIGraphicsGetCurrentContext() ];
    UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return snapshot;
}

@end


#pragma mark - BLWebViewController

@interface BLWebViewController ()<UIGestureRecognizerDelegate, TSWebViewDelegate> {
    JSExcuteObject  *_excuteJS;
    UIPanGestureRecognizer *_panLeft;
    BOOL            _isPanning;
}

@property (nonatomic, strong) JSContext *jsContext;
@property (nonatomic, strong) UIBarButtonItem *backButtonItem;
@property (nonatomic, strong) UIBarButtonItem *closeButtonItem;
@property (nonatomic, strong) UIButton  *refreshBtn;
@property (nonatomic, strong) NSString  *webTitle;
@property (nonatomic, strong) WKWebView *webView;

@property (nonatomic, strong) NSMutableArray *webSnapshots;
@property (nonatomic, strong) UIImageView *snapshotFont;
@property (nonatomic, strong) UIImageView *snapshotBehind;

@end

@implementation BLWebViewController

- (UIButton *)shareBtn {
    // TODO: 外部有使用到该按钮？
    return nil;
}

- (void)dealloc {
    for (NSString *name in ScriptNames) {
        [[_webView configuration].userContentController removeScriptMessageHandlerForName:name];
    }
    [_webView cleanForDealloc];
    _jsContext = nil;
    NSLog();
}

-(instancetype)init{
    self = [super init];
    if (self){
      
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self initUI];
    //[self.rightBarButton setTitle:@"•••" forState:UIControlStateNormal];
    [self.rightBarButton addTarget:self action:@selector(clickRightBtn) forControlEvents:UIControlEventTouchUpInside];
    self.rightBarButton.hidden = _shareBtnHidden;
    self.refreshBtn.hidden = _refreshBtnHidden;
    [self loadFirstPageWebView];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)initUI {
    //if (self.navigationController && !self.navigationItem.rightBarButtonItem) {
        self.navigationItem.rightBarButtonItem = ({
            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
            button.frame = CGRectMake(0, 0, 30, 40);
            button.enabled = NO;
            button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
            UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
            item;
        });
    //}
    
    UIImage *image = [UIImage imageNamed:@"navibar_more"];
    [self.rightBarButton setImage:image forState:UIControlStateNormal];
    [self.view addSubview:self.webView];
    if (self.screenEdgePanGestureRecognizer != nil) {
        [_webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:self.screenEdgePanGestureRecognizer];
    }
    
    
    self.navigationItem.leftBarButtonItems = @[self.backButtonItem];
    
    UIButton *refreshBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [refreshBtn setBackgroundImage:[UIImage imageNamed:@"bb_post_list_refresh"] forState:UIControlStateNormal];
    [refreshBtn sizeToFit];
    [self.view addSubview:refreshBtn];
    [refreshBtn addTarget:self action:@selector(refreshWebView:) forControlEvents:UIControlEventTouchUpInside];
    self.refreshBtn = refreshBtn;
    
    self.webView.frame = self.view.bounds;
    self.refreshBtn.frame = (CGRect){CGRectGetWidth(self.view.bounds)-CGRectGetWidth(refreshBtn.bounds)-15, CGRectGetHeight(self.view.bounds)-CGRectGetHeight(refreshBtn.bounds)-20};
}

- (BOOL)scrollsToTop {
    return YES;
}

- (void)webViewGoback {
    NSLog();
    if ([_webView canGoBack]) {
        [_webView goBack];
    }
    else {
        [self.navigationController popViewControllerAnimated:YES];
    }
}

- (void)popFunction {
    [self webViewGoback];
}

#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    completionHandler();
}

#pragma mark - WKWebView Delegate

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSLog();
    WKNavigationActionPolicy policy = WKNavigationActionPolicyAllow;
    NSURL *url = navigationAction.request.URL;
    NSString *absoluteString = url.absoluteString;
    NSString *tel = absoluteString.lowercaseString;
    if ([tel hasPrefix:@"tel://"] || [tel hasPrefix:@"telprompt://"]) {
        tel = [tel stringByReplacingOccurrencesOfString:@"tel://" withString:@"telprompt://"];
        NSURL *telURL = [NSURL URLWithString:tel];
        //telprompt:// premopt before call
        if ([[UIApplication sharedApplication] canOpenURL:telURL]) {
            [[UIApplication sharedApplication] openURL:telURL];
        }
    }
    
    if (navigationAction.navigationType==WKNavigationTypeBackForward) {
        WKBackForwardList *backForwardList = webView.backForwardList;
        NSString *title = backForwardList.currentItem.title;
        if (title.length==0) {
            title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
        }
        self.webTitle = title;
        self.title = title;
        
        [self closeButtonHide:!webView.canGoBack];
    }
    decisionHandler(policy);
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
    BOOL canGoBack = [webView canGoBack];
    NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    self.webTitle = title;
    self.title = title;
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
    if (error.code==NSURLErrorTimedOut) {
    }
}

- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
    if (error.code==NSURLErrorTimedOut) {
    }
}
/*
#pragma mark - UIWebViewDelegate

#pragma mark - Web Context
- (void)webView:(UIWebView *)webView didCreateJavaScriptContext:(JSContext*)ctx {
    if (!_jsContext || _jsContext!=ctx) {
        NSLog(@"%@-%@", _jsContext,  ctx);
        _jsContext = ctx;
        _jsContext[@"local_obj"]=[JSExcuteObject JSExcuteObjectWithContext:_jsContext];
        _jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
            //context.exception = exceptionValue;
            NSLog(@"异常信息：%@", exceptionValue);
        };
    }
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSURL *url = request.URL;
    NSString *absoluteString = url.absoluteString;
    
    if ([absoluteString hasPrefix:@"http"]) {
        switch (navigationType) {
            case UIWebViewNavigationTypeLinkClicked:
            case UIWebViewNavigationTypeFormSubmitted:
            case UIWebViewNavigationTypeOther:
            {
                if (navigationType==UIWebViewNavigationTypeOther) {
                    NSString* documentURL = [[request mainDocumentURL] absoluteString];
                    if( [absoluteString isEqualToString:documentURL]) {
                        //if they are the same this is a javascript href click to open an new page
                        // refer to: http://tech.vg.no/2013/09/13/dissecting-javascript-clicks-in-uiwebview/
                        [self.webSnapshots addObject:webView.snapshot];
                    }
                }
                else {
                    [self.webSnapshots addObject:webView.snapshot];
                }
            }
                break;
            default:
                break;
        }
    }
    return YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    BOOL canGoBack = [self.webView canGoBack];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
        self.webTitle = title;
        self.title = title;
    });
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    if (error.code==NSURLErrorTimedOut) {
    }
}

#pragma mark - UIGestureRecognizer

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if (self.screenEdgePanGestureRecognizer && [gestureRecognizer isEqual:self.screenEdgePanGestureRecognizer]) {
        return _web.canGoBack?NO:YES;
    }
    BOOL should = _panLeft==gestureRecognizer&&_web.canGoBack;
    return should;
}

- (void)edgeLeftPanDetected:(UIScreenEdgePanGestureRecognizer*)gesture {
    if (gesture.state == UIGestureRecognizerStateBegan) {
        CGPoint translation = [gesture translationInView:self.view]; //.x>0,向右滑动
        if (translation.x>0) {
            _isPanning = YES;
            UIImage *grab = self.web.snapshot;
            self.snapshotBehind.image = self.webSnapshots.lastObject;
            self.snapshotFont.image = grab;
            self.snapshotBehind.frame = _web.frame;
            self.snapshotFont.frame = self.snapshotBehind.frame;
            
            [self.view insertSubview:self.snapshotBehind aboveSubview:_web];
            [self.view insertSubview:self.snapshotFont aboveSubview:self.snapshotBehind];
            NSLog(@"%@", self.snapshotFont);
        }
    }
    else if (gesture.state == UIGestureRecognizerStateChanged) {
        if (_isPanning) {
            CGPoint translation = [gesture translationInView:self.view]; //.x>0,向右滑动
            CGRect frame = self.snapshotFont.frame;
            frame.origin.x = MAX(translation.x, 0);
            self.snapshotFont.frame = frame;
        }
    }
    else if (gesture.state == UIGestureRecognizerStateEnded) {
        if (_isPanning&&self.snapshotFont.superview) {
            CGPoint translation = [gesture translationInView:self.view]; //.x>0,向右滑动
            CGFloat maxX = CGRectGetMaxX(_web.frame);
            CGPoint velocity = [gesture velocityInView:self.view]; // 判断是否快速滑动
            // 右滑，快速滑动或滑动超过屏幕的一半了
            BOOL goBack = (translation.x>0 && (velocity.x>1000 || fabs(translation.x)>maxX/2.0));
            CGRect frame = self.snapshotFont.frame;
            NSTimeInterval dur = 0.5*(goBack?(maxX-frame.origin.x):frame.origin.x)/maxX;
            frame.origin.x = goBack?maxX:0.0;
            [UIView animateWithDuration:dur animations:^{
                self.snapshotFont.frame = frame;
                if (goBack) {
                    [self popFunction];
                }
            } completion:^(BOOL finished) {
                if (finished) {
                    if (goBack) {
                        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                            [self.snapshotBehind removeFromSuperview];
                        });
                    }
                    else {
                        [self.snapshotBehind removeFromSuperview];
                    }
                    [self.snapshotFont removeFromSuperview];
                }
            }];
            NSLog(@"%@", self.snapshotFont);
        }
    }
}
*/
#pragma mark - Events

- (BOOL)isCloseButtonItemHidden {
    return !_closeButtonItem || ![self.navigationItem.leftBarButtonItems containsObject:_closeButtonItem];
}

- (void)closeButtonHide:(BOOL)hide {
    if (hide) {
        NSArray *lefts = @[self.navigationItem.leftBarButtonItems.firstObject];
        [self.navigationItem setLeftBarButtonItems:lefts];
    }
    else {
        NSArray *lefts = @[self.navigationItem.leftBarButtonItems.firstObject, self.closeButtonItem];
        [self.navigationItem setLeftBarButtonItems:lefts];
    }
}

- (void)clickRightBtn {
}

- (void)setUrl:(NSString *)url {
    _url = url;
    NSLog(@"Open Web URL: %@", _url);
}

- (void)setShareBtnHidden:(BOOL)hidden {
    _shareBtnHidden = hidden;
    self.rightBarButton.hidden = hidden;
}

- (void)setRefreshBtnHidden:(BOOL)refreshBtnHidden
{
    _refreshBtnHidden = refreshBtnHidden;
    self.refreshBtn.hidden = refreshBtnHidden;
}

- (void)setScrollsToTopEnable:(BOOL)scrollsToTop {
    self.webView.scrollView.scrollsToTop = scrollsToTop;
}

- (BOOL)scrollsToTopEnable {
    return self.webView.scrollView.scrollsToTop;
}

- (void)closeWeb:(UIButton *)btn {
    NSLog(@"--------");
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)loadFirstPageWebView {
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:self.url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
    [_webView loadRequest:request];
    [_webView removeCache];
}

- (void)refreshWebView:(UIButton *)btn {
    [self refreshWebView];
}

- (void)refreshWebView {
    if (_webView.isLoading) {
        [_webView stopLoading];
    }
    
    WKWebView *webView = (WKWebView *)self.webView;
    if (webView.URL && webView.URL.absoluteString.length > 0) {
        [webView reload];
    }
    else {
        [self loadFirstPageWebView];
    }
}

- (void)recreateWebView
{
    [self.webView removeFromSuperview];
    _webView = nil;
    if (self.screenEdgePanGestureRecognizer != nil) {
        [_webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:self.screenEdgePanGestureRecognizer];
    }
    [self.view addSubview:self.webView];
    
    self.webView.frame = self.view.bounds;
}

#pragma mark - Getters
- (WKWebView *)webView {
    if (!_webView) {
        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        
        WKUserContentController *controller = configuration.userContentController;
        JSExcuteObject *jsObj = [[JSExcuteObject alloc] init];
        for (NSString *name in ScriptNames) {
            [controller addScriptMessageHandler:jsObj name:name];
        }
        
        CGRect frame = self.view.bounds;
        WKWebView *view = [[WKWebView alloc] initWithFrame:frame configuration:configuration];
        view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        view.allowsBackForwardNavigationGestures = YES;
        view.navigationDelegate = self;
        view.UIDelegate = self;
        jsObj.webView = view;
        if (self.screenEdgePanGestureRecognizer != nil) {
            [view.scrollView.panGestureRecognizer requireGestureRecognizerToFail:self.screenEdgePanGestureRecognizer];
        }
        _webView = view;
    }
    return _webView;
}
//- (UIWebView *)web {
//    if (!_web) {
//        if (UseWKWebView()) {
//            WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
//
//            WKUserContentController *controller = configuration.userContentController;
//            JSExcuteObject *jsObj = [[JSExcuteObject alloc] init];
//            for (NSString *name in ScriptNames) {
//                [controller addScriptMessageHandler:jsObj name:name];
//            }
//
//            CGRect frame = self.view.bounds;
//            WKWebView *view = [[WKWebView alloc] initWithFrame:frame configuration:configuration];
//            view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
//            view.allowsBackForwardNavigationGestures = YES;
//            view.navigationDelegate = self;
//            view.UIDelegate = self;
//            jsObj.webView = view;
//            if (self.screenEdgePanGestureRecognizer != nil) {
//                [view.scrollView.panGestureRecognizer requireGestureRecognizerToFail:self.screenEdgePanGestureRecognizer];
//            }
//            _web = (id)view;
//        }
//        else {
//            CGRect frame = self.view.bounds;
//            UIWebView *view = [[UIWebView alloc] initWithFrame:frame];
//            _web = (id)view;
//            view.scalesPageToFit = YES;
//            view.delegate = self;
//            view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
//
//            _panLeft = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(edgeLeftPanDetected:)];
//            _panLeft.delegate = self;
//            //panLeft.edges = UIRectEdgeLeft;
//            if (self.screenEdgePanGestureRecognizer != nil) {
//                [_panLeft requireGestureRecognizerToFail:self.screenEdgePanGestureRecognizer];
//            }
//            if (self.screenEdgePanGestureRecognizer != nil) {
//                [view.scrollView.panGestureRecognizer requireGestureRecognizerToFail:self.screenEdgePanGestureRecognizer];
//            }
//            [view addGestureRecognizer:_panLeft];
//        }
//    }
//    return _web;
//}

- (NSMutableArray *)webSnapshots {
    if (!_webSnapshots) {
        _webSnapshots = [NSMutableArray arrayWithCapacity:0];
    }
    return _webSnapshots;
}

- (UIImageView *)snapshotFont {
    if (!_snapshotFont) {
        _snapshotFont =[[UIImageView alloc] initWithFrame:_webView.bounds];
        _snapshotFont.layer.shadowColor = [UIColor blackColor].CGColor;
        //shadowOffset阴影偏移,右下>0
        _snapshotFont.layer.shadowOffset = CGSizeMake(-4,-3);
        _snapshotFont.layer.shadowOpacity = 0.8;
        _snapshotFont.layer.shadowRadius = 6;
    }
    return _snapshotFont;
}

- (UIImageView *)snapshotBehind {
    if (!_snapshotBehind) {
        _snapshotBehind =[[UIImageView alloc] initWithFrame:_webView.bounds];
    }
    return _snapshotBehind;
}

- (UIBarButtonItem *)backButtonItem
{
    if (!_backButtonItem) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.exclusiveTouch = YES;
        [button setImage:[UIImage imageNamed:@"返回"] forState:UIControlStateNormal];
        button.titleLabel.font = [UIFont systemFontOfSize:15];
//        [button setTitle:@"返回" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(popFunction) forControlEvents:UIControlEventTouchUpInside];
        [button sizeToFit];
        _backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    }
    return _backButtonItem;
}

- (UIBarButtonItem *)closeButtonItem
{
    if (!_closeButtonItem) {
        UIButton *backBtn = (UIButton *)self.backButtonItem.customView;
        UIButton *closeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        closeBtn.contentEdgeInsets = (UIEdgeInsets){0, 10, 0, 10};
        closeBtn.titleLabel.font = backBtn.titleLabel.font;
        
        [closeBtn addTarget:self action:@selector(closeWeb:) forControlEvents:UIControlEventTouchUpInside];
        [closeBtn setContentEdgeInsets:(UIEdgeInsets){0,0,0,0}];
        [closeBtn sizeToFit];
        _closeButtonItem = [[UIBarButtonItem alloc] initWithCustomView:closeBtn];
    }
    return _closeButtonItem;
}

@end


@implementation BLWebViewController (HideCloseButton)

- (void)setHideCloseButton {
    [self closeButtonHide:YES];
}

@end
